//
// @Auther: by wujehy 
// @Email:wujehy@qq.com
// @Data:2020/9/11
// @Time:1:00 下午
//
//

#include <iostream>
#include "NetworkManager.h"
#include "base_types.h"
#include "glog/logging.h"
#include <memory>

using boost::asio::ip::tcp;
using namespace GeeJoan;

void NetworkManager::init()
{

}

void NetworkManager::start()
{
    this->do_accept();
}

void NetworkManager::do_accept()
{
    acceptor_.async_accept(
            [this](boost::system::error_code ec, tcp::socket socket)
            {
                int current = this->clientid++;
                LOGINFO << " current net client id = " << current;
//                m_mutex.unlock();
//                this->clients[current]= std::move(socket);
                if (!ec)
                {
                    LOGINFO << " new connect" << std::endl;
                    // 链接
                    std::shared_ptr<Connection> current_client = std::make_shared<Connection>( std::move( socket ), current );
                    // 将客户端保存到map
                    LOGINFO << " inster client " << current;
                    this->m_client_map.insert( std::pair<int, std::shared_ptr<Connection>>( current, current_client ));
                    LOGINFO << " inster success" << current;
                    // 启动 当前客户当前任务
                    current_client->init();
                    current_client->init_complete( globalContext );
                    current_client->start();
                }
                do_accept();
            } );
}

NetworkManager::NetworkManager(boost::asio::io_context &io_context, unsigned short port) : acceptor_( io_context, {tcp::v4(), port} )
{

}

int NetworkManager::sendMsg(std::unique_ptr<HanderDataType> header, StatusCodeTypeEnum code, const std::string &msg, std::function<void(int)> callback)
{
    LOGINFO<<"header->clientid = " << int (header->clientid);
    auto find = m_client_map.find( header->clientid );

    if (find == m_client_map.end())
    {
        LOGINFO << " not find client ";
        //callback(-1);
        return -1;
    }
    boost::system::error_code ec;
    //　拼接回包内容
    std::string respMsg;
    respMsg.push_back( header->modtype );
    respMsg.push_back( header->subtype );
    respMsg.push_back( header->ctaskid );
    respMsg.push_back( code );
    Buffer_Len_DataType dataType;
    dataType.len16 = msg.length();
    respMsg.push_back(dataType.len8[1]);
    respMsg.push_back(dataType.len8[0]);
//    respMsg.push_back( msg.length());
    respMsg.append( msg );
    find->second->do_write( respMsg, ec );
    if (ec.failed())
    {
        if (callback) callback( -1 );
        LOGINFO << " send ec : " << ec.message();
    } else
    {
        if (callback)callback( 0 );
        LOGINFO << " send success";
    }

    return 0;
}

int NetworkManager::getOnlineCount() const
{
    return m_client_map.size();
}

void NetworkManager::init_complete(Global_Context *context)
{
    this->globalContext = context;
}

int NetworkManager::remove_client(int id)
{
    auto find = m_client_map.find( id );

    if (find == m_client_map.end())
    {
        LOGINFO << " not find client ";
        //callback(-1);
        return -1;
    }
    m_client_map.erase( id );

    return 0;
}

void NetworkManager::close_client(int id)
{
    auto find = m_client_map.find( id );

    if (find == m_client_map.end())
    {
        LOGINFO << " not find client ";
        //callback(-1);
        return;
    }

    find->second->close();
    m_client_map.erase( id );
}

NetworkManager::~NetworkManager()
{

}
